import { Directive } from 'vue';
// 针对 el-input做的限制，只能输入正整数
export const intDirective: Directive = {
  mounted(el: HTMLElement, binding) {
    const input = el.querySelector('input') as HTMLInputElement;
    const maxValue = binding.value;
    // 将最大值转换为数字，确保值有效
    const max = maxValue ? parseInt(maxValue as string, 10) : null;
    const validateInput = () => {
      let value = input.value.replace(/\D/g, ''); // 去除非数字字符
      // 如果值是0，清空输入框
      if (value === '0') {
        value = '';
      }
      // 如果输入值无效或不大于0，清空输入框
      if (!value || parseInt(value, 10) <= 0) {
        value = '';
      } else if (max !== null) {
        // 限制输入值在 1 到 maxValue 之间
        value = Math.min(Math.max(parseInt(value, 10), 1), max).toString();
      }
      // 如果值有变化则更新输入框
      if (input.value !== value) {
        input.value = value;
        trigger(input, 'input');
      }
    };

    input.addEventListener('input', validateInput);
    input.addEventListener('blur', validateInput);
  },
  updated(el: HTMLElement, binding) {
    const maxValue = binding.value;
    const input = el.querySelector('input') as HTMLInputElement;
    const max = maxValue ? parseInt(maxValue as string, 10) : null;
    // 如果最大值变化，重新校验输入值
    if (max !== null && input.value) {
      let value = parseInt(input.value, 10);
      if (value > max) {
        input.value = max.toString();
        trigger(input, 'input');
      } else if (value < 1) {
        input.value = '';
        trigger(input, 'input');
      }
    }
  },
};

// 针对 el-input做的限制，只能保留两位小数点的价格
export const priceDirective = {
  mounted(el: HTMLElement) {
    const input = el.querySelector('input') as HTMLInputElement

    input.addEventListener('keyup', (e) => {
      // 只允许输入数字和一个小数点，且保证小数点只能出现一次且在合法位置
      input.value = input.value.replace(/[^\d.]/g, '') // 替换非数字和小数点之外的字符
      input.value = input.value.replace(/^\./, '') // 如果开头是小数点，则移除
      input.value = input.value.replace(/\.{2,}/g, '.') // 保证小数点只能出现一次
      input.value = input.value.replace(/^(\-)*(\d+)\.(\d\d).*/, '$1$2.$3') // 限制只能输入两位小数

      // 手动触发 'input' 事件，以便 Vue.js 可以识别输入变化
      trigger(input, 'input')
    })

    input.addEventListener('blur', (e) => {
      // 如果最终输入为0，则置空输入框
      // if (parseFloat(input.value) === 0) {
      //   input.value = ''
      // }
      // 手动触发 'input' 事件，以便 Vue.js 可以识别输入变化
      trigger(input, 'input')
    })
  }
}

// 针对价格显示处理，保留两位小数
export const priceDisplayDirective = {
  mounted(el: HTMLElement, binding: any) {
    const value = binding.value
    const num = Number(value)
    el.textContent = isNaN(num) ? '0.00' : num.toFixed(2)
  },
  updated(el: HTMLElement, binding: any) {
    const value = binding.value
    const num = Number(value)
    el.textContent = isNaN(num) ? '0.00' : num.toFixed(2)
  }
}

// 手动触发事件
const trigger = (el: HTMLElement, type: string) => {
  // 检查是否已经触发过该事件
  if (el.dataset[`${type}Triggered`]) {
    console.warn(`Event "${type}" has already been triggered on this element.`);
    return;
  }

  // 标记事件已触发
  el.dataset[`${type}Triggered`] = 'true';

  // 创建并触发事件
  const e = new Event(type, { bubbles: true, cancelable: true });
  el.dispatchEvent(e);

  // 清除标记（如果需要）
  setTimeout(() => {
    delete el.dataset[`${type}Triggered`];
  }, 0);
};
// 注册全局指令
import { App } from 'vue'

export function registerDirectives(app: App) {
  app.directive('int', intDirective)
  app.directive('price', priceDirective)
  app.directive('priceDisplay', priceDisplayDirective)
}
